package com.jacob.androidframe.base;

import java.util.List;
import java.util.Map;

import android.content.Context;
import android.view.LayoutInflater;
import android.widget.BaseExpandableListAdapter;

/**
 * 本类是所有ExpandableListAdapter的父类，只能用于ExpandableList。 用来封装和业务无关的代码。
 * 所有继承本类的Adapters需要保证，getCombinedChildId(long, long) 和 getCombinedGroupId(long)方法能正确地从Group或Child的ID中生成唯一的ID号。
 * 
 * 由于数据源使用了Map存放，所以建议重写Group类和Child类的equals()方法、hashCode()方法。
 * 
 * @author 王超
 * 
 * @param <G>
 *            Group类，对应ExpandableList的一级菜单项。
 * @param <C>
 *            Child类，对应ExpandableList的二级菜单项。
 */
public abstract class AdapterExpandableListBase<G, C> extends BaseExpandableListAdapter
{
    // 上下文对象
    private Context         mContext;
    // 存放Group数据的List
    private List<G>         mGroupList;
    // 存放Child数据的List
    private Map<G, List<C>> mChildMap;
    // 用来根据Item布局文件生成View
    private LayoutInflater  mLayoutInflater;

    /**
     * 构造Adapter
     * 若数据源是Adapter自己创建的，对应的参数传入null。然后调用setGroupList(List<G>)方法、setChildMap(Map<G, List<C>>)方法设置数据源。
     * 
     * @param pContext
     *            上下文对象
     * @param pGroupList
     *            Group数据源。传入包含Group对象的List。
     * @param pChildMap
     *            Child数据源。传入Map对象，其中Key为Group对象，Value为包含Child对象的List。
     */
    public AdapterExpandableListBase(Context pContext, List<G> pGroupList, Map<G, List<C>> pChildMap)
    {
        super();
        mContext = pContext;
        mGroupList = pGroupList;
        mChildMap = pChildMap;
        mLayoutInflater = LayoutInflater.from(mContext);
    }

    @Override
    public int getGroupCount()
    {
        return mGroupList.size();
    }

    @Override
    public int getChildrenCount(int pGroupPosition)
    {
        G _GroupObject = mGroupList.get(pGroupPosition);
        List<C> _ChildList = mChildMap.get(_GroupObject);

        return _ChildList.size();
    }

    @Override
    public G getGroup(int pGroupPosition)
    {
        return mGroupList.get(pGroupPosition);
    }

    @Override
    public C getChild(int pGroupPosition, int pChildPosition)
    {
        G _GroupObject = mGroupList.get(pGroupPosition);
        List<C> _ChildList = mChildMap.get(_GroupObject);

        return _ChildList.get(pChildPosition);
    }

    /**
     * 得到指定位置的Group对象ID。这个ID必须在mGroupList中唯一。
     * 默认返回Group对象在List中的位置，建议子类覆盖。
     */
    @Override
    public long getGroupId(int pGroupPosition)
    {
        return pGroupPosition;
    }

    /**
     * 得到和指定位置的Child的ID。这个ID必须在同组内唯一。
     * 默认返回Child在List中的位置，建议子类覆盖。
     */
    @Override
    public long getChildId(int pGroupPosition, int pChildPosition)
    {
        return pChildPosition;
    }

    /**
     * 声明Group和Child的ID是否是底层稳定的。
     * 默认返回false，建议子类覆盖。
     * 
     * @return 若相同的ID一定表示相同的对象，返回true；否则返回false。
     */
    @Override
    public boolean hasStableIds()
    {
        return false;
    }

    /**
     * 指定位置的Child是否可以被选择。
     */
    @Override
    public abstract boolean isChildSelectable(int pGroupPosition, int pChildPosition);

    /**
     * 通知关联的View，底层数据有变更，需要刷新显示。
     * 需要子类重写。
     */
    @Override
    public void notifyDataSetChanged()
    {
        super.notifyDataSetChanged();
    }

    protected List<G> getGroupList()
    {
        return mGroupList;
    }

    protected void setGroupList(List<G> mGroupList)
    {
        this.mGroupList = mGroupList;
    }

    protected Map<G, List<C>> getChildMap()
    {
        return mChildMap;
    }

    protected void setChildMap(Map<G, List<C>> mChildMap)
    {
        this.mChildMap = mChildMap;
    }

    protected Context getContext()
    {
        return mContext;
    }

    protected LayoutInflater getLayoutInflater()
    {
        return mLayoutInflater;
    }

}
